1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Laravelにおけるデータベース操作の基本

1
Posted at

はじめに

Laravelは非常にDBとの関連性が深いフレームワークです。
では、どのようにDBと関わっているのでしょうか。

今回は、LaravelでDBを扱う際によく使用する MigrationModelSeederEloquent について整理していきます。

LaravelのDB関連要素について

Laravelには、DBをスムーズに扱うための素晴らしいエコシステムが用意されています。

Migration:データを格納する「家(テーブル)」

Model:「住人(または窓口)」

Seeder:初期データを運んでくる「配達人」

Eloquent:欲しいデータをピンポイントで呼び出す「インターホン」

言葉だけだとイメージしづらい部分もあるので、それぞれの詳細と「実務でどう向き合うか」を見ていきましょう。

Migration

実物のDBに対して「どんなテーブルを作るか」「どんなカラムを持たせるか」をコードで定義したものがMigration(マイグレーション)です。

<?php

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

return new class extends Migration
{
    /**
     * Run the migrations.
     */
    public function up(): void
    {
        Schema::create('users', function (Blueprint $table) {
            $table->id();
            $table->string('name');
            $table->string('email')->unique();
            $table->timestamp('email_verified_at')->nullable();
            $table->string('password');
            $table->rememberToken();
            $table->timestamps();
        });
    }

    /**
     * Reverse the migrations.
     */
    public function down(): void
    {
        Schema::dropIfExists('users');
    }
};

Migrationを使用する上でのポイント

直感的なメソッド指定: string() で文字列、unique() で重複不可の制約、nullable() でNULLの許可などをサクサク指定できます。

運用での便利さ: チーム開発で「このテーブル、どんな構造だっけ?」となったとき、わざわざGUIツールでDBを覗かなくても、このファイルを読めば一発で理解できます。

upとdownの対構造: php artisan migrate で up() が走り、ミスって戻したいときは down() の処理(この例ならテーブル削除)が走る仕組みです。論理削除を導入したいときは、ここに softDeletes() を足したりします。

Model

Migrationでテーブルを作ったら、次に用意するのが「Model(モデル)」です。ここが、PHPの世界とDBの世界を繋ぐ架け橋になります。

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;

class Transaction extends Model
{
    use HasFactory;

    protected $fillable = [
        'occurred_on',
        'type',
        'category_id',
        'amount',
        'memo',
    ];

    protected $casts = [
        'occurred_on' => 'date',
        'amount' => 'integer',
    ];

    public function category(): BelongsTo
    {
        return $this->belongsTo(Category::class);
    }
}

Modelを使ううえでのポイント

実務では、このModelクラスを経由してあらゆるDB操作(後述のEloquentなど)を行います。

// 最もシンプルな、ID指定でのデータ取得
$transaction = Transaction::find(1);
echo $transaction->amount; // プロパティのようにカラムの値を取り出せる

また、ビジネスロジックをまとめる「Serviceクラス」などでは、上記のようにModelを静的に呼び出すだけでなく、依存性の注入(DI)を使ってコンストラクタで受け取るパターンもよく使われます。

// ServiceクラスなどでのDIの例
public function __construct(
    private Transaction $transaction
) {}
 
public function getTransactionData($id)
{
    // DIしたインスタンス経由で取得(テストが書きやすくなるメリットも)
    return $this->transaction->find($id);
}

Controller、Service、Seeder、あるいはデバッグ用の php artisan tinker まで、Laravel開発においてModelを触らない日はありません。

Seeder

Migrationが空の箱(テーブル)を作るものなら、Seeder(シーダー)はその中に初期データやテストデータを流し込むための仕組みです。

<?php

namespace Database\Seeders;

use App\Models\Category;
use Illuminate\Database\Seeder;

class CategorySeeder extends Seeder
{
    public function run(): void
    {
        $categories = [
            ['name' => '給与', 'type' => 'income', 'color' => '#2563eb'],
            ['name' => '副業', 'type' => 'income', 'color' => '#16a34a'],
            ['name' => '食費', 'type' => 'expense', 'color' => '#dc2626'],
            ['name' => '日用品', 'type' => 'expense', 'color' => '#ea580c'],
            ['name' => '交通費', 'type' => 'expense', 'color' => '#7c3aed'],
            ['name' => '娯楽', 'type' => 'expense', 'color' => '#0891b2'],
        ];

        foreach ($categories as $category) {
            Category::query()->create($category);
        }
    }
}

Seederを使ううえでのポイント

マスタデータの管理に最適: サービスを動かす上で必須となる「カテゴリ一覧」「権限一覧」「ステータスコード」などをGit管理し、誰の環境でも同じ初期状態を作れます。

テスト環境の構築: 大量に検証用データが欲しい場合は、Seederの中で Factory や Faker というダミーデータ生成ツールと組み合わせるのが王道です。

Seederを実務運用する上で気を付けておきたいこと

テストデータ(特にメールアドレスや電話番号など)を仕込む際、誤って本番環境や外部の通知APIと連携して「実在する宛先にテストメールが飛んでしまった!」という事故は絶対に避けたいところ。ダミーデータは安全な値(例: example.com ドメインなど)を設定する癖をつけておきましょう。

Eloquent

「生のSQLを書くの、ちょっとしんどいな…」という開発者の負担を激減させてくれるのが、Laravel自慢のORM「Eloquent(エロクアント)」です。プログラムとしてごく自然にDB操作が書けます。

$monthTransactions = Transaction::with('category')
    ->whereBetween('occurred_on', [
        $startOfMonth->toDateString(),
        $endOfMonth->toDateString(),
    ])
    ->get();

Eloquentを使用する上でのポイント

リレーションがとにかく楽: with('category') と書いておく(Eagerロード)だけで、裏側でいい感じに結合(または追跡クエリ)してくれます。データを取り出した後も、$transaction->category->name のように直感的にアクセスできます。

Collection型の恩恵: get() で取得した結果は、ただの配列ではなく「Collectionクラス」にラップされます。これが非常に強力で、PHP側でさらに map() や filter()、sum() を使ってデータを加工しやすくなります。

Eloquentを使ううえで気を付けたいこと

複雑な条件をすべてEloquentだけで解決しようとすると、メソッドチェーンやクロージャのネストが深くなり、逆に「このSQL、裏でどう動いてるんだ…?」と見づらくなることもあります。
チーム開発では、パフォーマンス(N+1問題など)を意識しつつ、「誰が見ても意図が伝わる綺麗なクエリ」を心がけるのが、脱・初心者の第一歩だったりします。

まとめ

今回は、Laravelのデータベース層を支える4つの基本要素を整理しました。
Migration でデータを迎える「家」を建て、
Model でプログラムと繋ぐ「住人」を置き、
Seeder という「配達人」に初期データを届けてもらい、
Eloquent という「インターホン」で任意のデータにアクセス。
最初は「覚えることが多くてややこしいな…」と感じるかもしれませんが、実はそれぞれが1つのアプリケーションを動かすために、役割を分担して連携し合っています。
この4つの関係性が頭の中で繋がると、新しく機能を実装するときの設計が驚くほどスムーズになり、開発がもっと楽しくなってくると思います

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?